package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.base.execption.XueChengPlusException;
import com.xuecheng.content.mapper.TeachplanMapper;
import com.xuecheng.content.mapper.TeachplanMediaMapper;
import com.xuecheng.content.model.dto.SaveTeachplanDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.model.dto.UploadMediaDto;
import com.xuecheng.content.model.po.Teachplan;
import com.xuecheng.content.model.po.TeachplanMedia;
import com.xuecheng.content.service.TeachplanMediaService;
import com.xuecheng.content.service.TeachplanService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 课程计划 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class TeachplanServiceImpl extends ServiceImpl<TeachplanMapper, Teachplan> implements TeachplanService {
    @Autowired
    private TeachplanMapper teachplanMapper;
    @Autowired
    private TeachplanMediaMapper teachplanMediaMapper;

    @Override
    public List<TeachplanDto> getTreeNodes(Long courseId) {
        List<TeachplanDto> teachplanDtos = teachplanMapper.selectTreeNodes(courseId);
        return teachplanDtos;
    }

    @Override
    public void saveTeachplan(SaveTeachplanDto dto) {
        Long teachplanId = dto.getId();
        //新增
        Teachplan teachplan = new Teachplan();
        BeanUtils.copyProperties(dto,teachplan);
        if(teachplanId==null){
            //在章节或小节尾加入
            int count = countCourseplan(dto.getCourseId(), dto.getParentid());
            teachplan.setOrderby(count+1);
            teachplan.setCreateDate(LocalDateTime.now());
            teachplanMapper.insert(teachplan);
        }
        //更新
        else {
            Teachplan teachplan1 = teachplanMapper.selectById(teachplanId);
            BeanUtils.copyProperties(dto,teachplan1);
            teachplan.setChangeDate(LocalDateTime.now());
            teachplanMapper.updateById(teachplan);
        }
    }
    //获取课程的数量
    public int countCourseplan(Long courseId,Long courseParentId){
        LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Teachplan::getCourseId,courseId).eq(Teachplan::getParentid,courseParentId);
        int count = this.count(wrapper);
        return count;
    }

    //删除课程计划和视频
    @Override
    @Transactional
    public void deleteTeachplan(Long teachplanId) {
        //当课程计划没有子节点时删除课程计划
        LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Teachplan::getParentid,teachplanId);
        //找当前节点的子节点
        List<Teachplan> teachplanList = teachplanMapper.selectList(wrapper);
        if(teachplanList.size()>0){
            throw new XueChengPlusException("关联小节，不能删除");
        }else {
            teachplanMapper.deleteById(teachplanId);
            //删除视频
            LambdaQueryWrapper<TeachplanMedia> teachplanMediaLambdaQueryWrapper = new LambdaQueryWrapper<>();
            teachplanMediaLambdaQueryWrapper.eq(TeachplanMedia::getTeachplanId,teachplanId);
            teachplanMediaMapper.delete(teachplanMediaLambdaQueryWrapper);
            //TODO：可以将后面的节点的orderby都上移，这样就在节点上下移动时不用那么麻烦，缺点当前操作要操作多次数据库
        }

    }

    //课程计划上移
    @Override
    @Transactional
    public void moveupTeachplan(Long teachplanId) {
        //当前节点
        Teachplan curTeachplan = teachplanMapper.selectById(teachplanId);
        //当前节点的orderby
        Integer curOrderby = curTeachplan.getOrderby();
        Long parentid = curTeachplan.getParentid();
        LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Teachplan::getParentid,parentid).eq(Teachplan::getCourseId,curTeachplan.getCourseId());
        //同一个父亲下的子节点
        List<Teachplan> teachplanList = teachplanMapper.selectList(wrapper);
        //比当前节点小的最大节点的orderby
        Integer lastOrderBy=0;
        if(teachplanList.size()>1){
            for (Teachplan t : teachplanList) {
                if(t.getOrderby()<curOrderby){
                    lastOrderBy=Math.max(t.getOrderby(),lastOrderBy);
                }
            }
            if(lastOrderBy==0){
                throw new XueChengPlusException("当前节点在顶部，不能上移");
            }
        }else {
            throw new XueChengPlusException("当前节点在顶部，不能上移");
        }
        LambdaQueryWrapper<Teachplan> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(Teachplan::getParentid,parentid)
                .eq(Teachplan::getOrderby,lastOrderBy)
                .eq(Teachplan::getCourseId,curTeachplan.getCourseId());
        //找到要交换的teachplan
        Teachplan lastTeachplan = teachplanMapper.selectOne(wrapper1);
        //开始交换
        //更新当前
        curTeachplan.setOrderby(lastOrderBy);
        curTeachplan.setChangeDate(LocalDateTime.now());
        teachplanMapper.updateById(curTeachplan);
        //更新交换的节点
        lastTeachplan.setOrderby(curOrderby);
        teachplanMapper.updateById(lastTeachplan);

    }

    //课程计划下移
    @Override
    @Transactional
    public void movedownTeachplan(Long teachplanId) {
        //当前节点
        Teachplan curTeachplan = teachplanMapper.selectById(teachplanId);
        //当前节点的orderby
        Integer curOrderby = curTeachplan.getOrderby();
        Long parentid = curTeachplan.getParentid();
        LambdaQueryWrapper<Teachplan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Teachplan::getParentid,parentid).eq(Teachplan::getCourseId,curTeachplan.getCourseId());
        //同一个父亲下的子节点
        List<Teachplan> teachplanList = teachplanMapper.selectList(wrapper);
        //比当前节点大的最小节点的orderby
        Integer nextOrderBy=Integer.MAX_VALUE;
        if(teachplanList.size()>1){
            for (Teachplan t : teachplanList) {
                if(t.getOrderby()>curOrderby){
                    nextOrderBy=Math.min(t.getOrderby(),nextOrderBy);
                }
            }
            if(nextOrderBy==Integer.MAX_VALUE){
                throw new XueChengPlusException("当前节点在底部，不能下移");
            }
        }else{
            throw new XueChengPlusException("当前节点在底部，不能下移");
        }
        LambdaQueryWrapper<Teachplan> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(Teachplan::getParentid,parentid)
                .eq(Teachplan::getOrderby,nextOrderBy)
                .eq(Teachplan::getCourseId,curTeachplan.getCourseId());
        //找到要交换的teachplan
        Teachplan lastTeachplan = teachplanMapper.selectOne(wrapper1);
        //开始交换
        //更新当前
        curTeachplan.setOrderby(nextOrderBy);
        curTeachplan.setChangeDate(LocalDateTime.now());
        teachplanMapper.updateById(curTeachplan);
        //更新交换的节点
        lastTeachplan.setOrderby(curOrderby);
        teachplanMapper.updateById(lastTeachplan);
    }

    //课程计划绑定视频
    @Override
    public void uploadmedia(UploadMediaDto uploadMediaDto) {
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        String mediaId = uploadMediaDto.getMediaId();
        Long teachplanId = uploadMediaDto.getTeachplanId();
        //根据teachplanId找到课程
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
        if(teachplan==null){
            throw new XueChengPlusException("课程不存在");
        }
        teachplanMedia.setCourseId(teachplan.getCourseId());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        teachplanMedia.setMediaFilename(uploadMediaDto.getFileName());
        teachplanMedia.setMediaId(mediaId);
        teachplanMedia.setTeachplanId(teachplanId);
        teachplanMediaMapper.insert(teachplanMedia);
    }

    //根据课程计划id和媒资id删除对应关系
    @Override
    public void deleteTeachplanMedia(Long teachplanId, String mediaId) {
        LambdaQueryWrapper<TeachplanMedia> teachplanMediaLambdaQueryWrapper = new LambdaQueryWrapper<>();
        teachplanMediaLambdaQueryWrapper.eq(TeachplanMedia::getMediaId,mediaId).eq(TeachplanMedia::getTeachplanId,teachplanId);
        teachplanMediaMapper.delete(teachplanMediaLambdaQueryWrapper);
    }
}
